<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型式继承</title>
  </head>
  <body>
    <h3>原型式继承</h3>
    <h4>相当于把所有的属性跟方法放在原型对象上了，类似于浅拷贝。</h4>
    <h4>缺点：无法传参，对象如果是复合数据类型的数据，会造成数据混乱。</h4>
    <script>
      let parentObj = {
        name: "未初始化的人",
        data: {
          a: 1,
          b: 2,
          c: 3,
        },
        sayData: function () {
          console.log(this.data);
        },
        setDataA: function () {
          this.data.a = 666;
        },
      };

      // 第一种方式，函数传参返回一个实例
      // 该实例对应的构造函数的原型指向了传参
      function createObj(obj) {
        function Fun() {
          // ... 这里不可以有方法以及属性，不然会覆盖Fun的原型对象上的方法以及属性
        }
        // 父类的公共方法以及属性需要放在这里，会被 "Fun.prototype = obj;" 覆盖...
        // ... Fun.prototype.name = "";
        Fun.prototype = obj;
        // 放在这里也不可以，会覆盖传进来的参数obj
        // ... Fun.prototype.name = 111;
        // ... Fun.prototype.sayName = function () {
        // ...   console.log(this.name);
        // ... };
        return new Fun();
      }

      // 就当成一个父类吧
      let parent = createObj(parentObj);
      console.log(parent);

      // 所以说，原型式继承，只能继承传进来的参数obj
      // 第二种方式创建obj，使用object.create()
      let parent2 = Object.create(parentObj);
      console.log(parent2);

      console.log(
        "=====通过上面的对比，可以得知，Object.create()，可以实现原型式继承..."
      );

      console.log("=====================");
      console.log("=====================");
      console.log("接下来要展示原型式继承的BUG...");

      // 就当成一个子类
      let children = Object.create(parent);
      children.job = "未找到工作";
      children.sayJob = function () {
        console.log(`${this.name} 的工作是${this.job}...`);
      };

      // 实例化2个子类对象
      // let person1 = Object.create(children);
      // let person2 = Object.create(children);

      // 真的不知道怎么初始化，没找到相关资料...
      // 这边就随便来了，有好建议欢迎交流.
      // person1.name = "钟先生";
      // person1.job = "程序员";

      // console.log(person1);
      // console.log(person2);

      // person1.sayJob();
      // person2.sayJob();

      // console.log("大概就是这样，一层套一层，还不能传参...");
      // console.log("=====================");
      // console.log("=====================");
      // console.warn("====这里如果使用了复合数据类型的话，也会出现数据混乱...");

      // 实例化2个子类对象
      let person1 = Object.create(children);
      let person2 = Object.create(children);

      // 初始化
      person1.name = "钟先生";
      person1.job = "程序员";

      person2.name = "刘小姐";
      person2.job = "清洁阿姨";

      // 未修改数据
      console.log("===未修改数据的时候...");
      person1.sayData();
      person2.sayData();

      console.log("===修改数据的时候...");
      person1.setDataA();
      person1.sayData();
      person2.sayData();

      console.log(person1);
      console.log(person2);
    </script>
  </body>
</html>
